/*java jdk 1.7+
# -*- coding: utf-8 -
'''
Created on 2020年05月10日
@author: zxyong 13738196011
'''*/

package com.zxy.tcp;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.Date;

import com.zxy.adminlog.UsAdmin_Log;
import com.zxy.business.Analyse_Data;
import com.zxy.common.Com_Fun;
import com.zxy.common.Com_Para;

public class ClientHandler extends Thread
{
	//#断线重连
	public int idtTimeOut = 60;
	private BufferedReader	reader;
	@SuppressWarnings("unused")
	private SocketAddress	sadd	= null;

	//#inputFlag网络链接是否正常
    public void set_dSockList(boolean inputFlag){
        String key = Com_Para.ServerIP+"|"+Com_Para.ServerPort;
        //#存在
        if(!Com_Para.dSockList.containsKey(key)){
        	Object[] objs = {0,new Date().getTime()};
            Com_Para.dSockList.put(key,objs);
        }
        if(inputFlag == false){
        	Object[] objAry = Com_Para.dSockList.get(key);
            if(Integer.valueOf(objAry[0].toString()) <= (int)(180 / this.idtTimeOut)+10)
                objAry[0] = Integer.valueOf(objAry[0].toString()) + 1;
            objAry[1] = new Date().getTime();
            Com_Para.dSockList.put(key,objAry);
        }
        else{
        	Object[] objs = {0,new Date()};
            Com_Para.dSockList.put(key,objs);
        }
    }	
	
    //#判断上次链接时间频率是否合规
    public boolean judge_dSock(){
    	String key = Com_Para.ServerIP+"|"+Com_Para.ServerPort;
    	if(!Com_Para.dSockList.containsKey(key)){
        	Object[] objs = {0,new Date().getTime()};
            Com_Para.dSockList.put(key,objs);
        }
    	Object[] objAry = Com_Para.dSockList.get(key);
        long starttime = new Date().getTime();
        if(Integer.valueOf(objAry[0].toString()) <= (int)(120 / this.idtTimeOut)+1)
            return true;
        else if(Integer.valueOf(objAry[0].toString()) <= (int)(120 / this.idtTimeOut)+4 && starttime >= Long.valueOf(objAry[1].toString()) + 600 * 1000)
            return true;
        else if(Integer.valueOf(objAry[0].toString()) <= (int)(120 / this.idtTimeOut)+7 && starttime >= Long.valueOf(objAry[1].toString()) + 3600 * 1000)
            return true;
        else if(Integer.valueOf(objAry[0].toString()) > (int)(120 / this.idtTimeOut)+7 && starttime >= Long.valueOf(objAry[1].toString()) + 12 * 3600 * 1000)
            return true;
        else
            return false;
    }
    
	public void run()
	{
		try
		{
			this.setName("ClientHandler_zxyong");
			if(java.util.Objects.equals(Com_Para.clientSocket,null)){
	            //#判断上次链接时间频率是否合规
	            if(!this.judge_dSock())
	                return;
	            System.out.println("connect local server:"+Com_Fun.DateTimeStr("yyyy-MM-dd HH:mm:ss"));
				Com_Para.clientSocket = new Socket(Com_Para.ServerIP,Com_Para.ServerPort);
				Com_Para.clientSocket.setKeepAlive(true);
				this.set_dSockList(true);
			}
		}
		catch(Exception e)
		{
            this.set_dSockList(false);
			Com_Fun.debug_in(e,this.toString(),"网络连接错误"+Com_Para.ServerIP + ":" + String.valueOf(Com_Para.ServerPort));
		}
//		InputStreamReader isReader = null;
		InputStream isIn = null;
		Date rightStart = new Date();
		while(true)
		{
			long temp = new Date().getTime() - rightStart.getTime();
			try
			{
				if(!java.util.Objects.equals(Com_Para.clientSocket,null)
						&& Com_Para.clientSocket.isBound()
						&& Com_Para.clientSocket.isConnected()
						&& !Com_Para.clientSocket.isClosed())
				{
					Com_Para.htServSockets.put("clientSocket",Com_Para.clientSocket);
					//以char[]形式接收
//					String CHSet = "UTF-8";
//					isReader = new InputStreamReader(Com_Para.clientSocket.getInputStream(),CHSet);//UTF-8 GBK
//					reader = new BufferedReader(isReader);
//					char[] Bytes = new char[Com_Para.clientSocket.getReceiveBufferSize()];
//					int iLength = reader.read(Bytes,0,Bytes.length);
					
					//以byte[]形式接收
					isIn = Com_Para.clientSocket.getInputStream();
					byte[] Bytes = new byte[Com_Para.clientSocket.getReceiveBufferSize()];
					int iLength = isIn.read(Bytes,0,Bytes.length);
					
					if(iLength > 0)
					{
//						char[] bytNew = new char[iLength];
//						System.arraycopy(Bytes, 0, bytNew, 0,iLength);
//						System.out.println("编码格式转换,GBK原始byte:"+strValue);
//						String strIP = Com_Para.clientSocket.getInetAddress().getHostAddress();// "0.0.0.0";
//						rightStart = new Date();
//						Analyse_Data ad = new Analyse_Data();
//						ad.SubClientRecBytes(iLength,bytNew,Com_Para.clientSocket,false,strIP);
					
						byte[] bytNew = new byte[iLength];
						System.arraycopy(Bytes, 0, bytNew, 0,iLength);	
						String strIP = Com_Para.clientSocket.getInetAddress().getHostAddress();// "0.0.0.0";
						rightStart = new Date();
						Analyse_Data ad = new Analyse_Data();
						ad.SubClientRecBytes(iLength,bytNew,Com_Para.clientSocket,false,strIP);
					}else if(iLength <= 0)
					{
						Analyse_Data ad = new Analyse_Data();
						try
						{
							// ad.SendSocket(new
							// StringBuilder("*"),Com_Para.clientSocket);
						}
						catch(Exception e)
						{
							Com_Fun.debug_in(e,this.toString(),"服务端已关闭链接3"+Com_Para.ServerIP + ":" + String.valueOf(Com_Para.ServerPort));
							Com_Para.clientSocket = null;
							Com_Para.htServSockets.remove("clientSocket");
						}
						rightStart = new Date();
					}
				}else if(temp / 1000 > 120)
				{
					try
					{
						if(java.util.Objects.equals(Com_Para.clientSocket,null) && this.judge_dSock())
						{
				            System.out.println("connect local server:"+Com_Fun.DateTimeStr("yyyy-MM-dd HH:mm:ss"));
							Com_Para.clientSocket = new Socket(Com_Para.ServerIP,Com_Para.ServerPort);
							Com_Para.clientSocket.setKeepAlive(true);
							this.set_dSockList(true);
							UsAdmin_Log uL = new UsAdmin_Log(Com_Para.ApplicationPath,new StringBuilder("尝试再次连接服务端成功"
									+ Com_Fun.DateTimeStr("yyyy-MM-dd HH:mm:ss:SSS")));
							try
							{
								uL.WriteLogSub("NetWork");
							}
							catch(IOException e)
							{
							}
							System.out.println("尝试再次连接服务端成功2："+ Com_Fun.DateTimeStr("yyyy-MM-dd HH:mm:ss:sss"));
							// Analyse_Data ad = new Analyse_Data();
							// ad.Send01(Com_Para.clientSocket);
						}
					}
					catch(Exception e)
					{
						Com_Fun.debug_in(e,this.toString(),"尝试再次连接服务端失败1：");
						Com_Para.clientSocket = null;
						Com_Para.htServSockets.remove("clientSocket");
						this.set_dSockList(false);
					}
					rightStart = new Date();
				}else
				{
//					System.out.println("客户端被服务端关闭连接："
//							+ Com_Fun.DateTimeStr("yyyy-MM-dd HH:mm:ss:sss"));
					Com_Para.htServSockets.remove("clientSocket");
					Com_Para.clientSocket = null;
//					this.set_dSockList(false);
				}
				Thread.sleep(300);
			}
			catch(Exception e)
			{
				if(temp / 1000 > 120)
				{
					try
					{
						if(this.judge_dSock()){
				            System.out.println("connect local server:"+Com_Fun.DateTimeStr("yyyy-MM-dd HH:mm:ss"));
							Com_Para.clientSocket = null;
							Com_Para.clientSocket = new Socket(Com_Para.ServerIP,Com_Para.ServerPort);
							// Com_Para.clientSocket.isBound();
							Com_Para.clientSocket.setKeepAlive(true);
							this.set_dSockList(true);
							Com_Fun.debug_in(e,this.toString(),"循环连接连接服务端成功4：");
						}
						// Analyse_Data ad = new Analyse_Data();
						// ad.Send01(Com_Para.clientSocket);
					}
					catch(Exception en)
					{
						Com_Fun.debug_in(en,this.toString(),"循环连接连接服务端失败5：");
						Com_Para.clientSocket = null;
						Com_Para.htServSockets.remove("clientSocket");
						this.set_dSockList(false);
					}
					rightStart = new Date();
				}
			}
		}
	}
}